fix: enforce back-channel logout on subsequent requests by rehydrating session state - #852
Merged
Merged
Conversation
…ross requests getState() reloaded user, id token, access token, scope, expiration, and refresh token from session storage but not the backchannel key, so on a subsequent request getBackchannel() was null and the enforcement check in getCredentials() short-circuited. Rehydrate the key from session storage and register it in SdkState's property defaults and validators so it is accepted.
nandan-bhat
reviewed
Aug 7, 2026
4 tasks
kishore7snehil
added a commit
that referenced
this pull request
Aug 31, 2026
…ersions (#862) ### Changes CI installs its dev tools from open version ranges and there is no committed `composer.lock`, so it recently pulled in a newer Rector (2.6.x). That version enables `IfToNullCoalescingAssignRector`, which is why the Rector job started failing on unrelated PRs. - The rule rewrites `if (null === $x) { $x = ...; }` guards to `$x ??= ...`, which is equivalent. - This affected four pre-existing spots: `src/Token.php`, `src/Token/Parser.php`, `src/Utility/HttpResponsePaginator.php`, and `src/Utility/HttpTelemetry.php`. - In `src/Token/Parser.php` the `@codeCoverageIgnore` markers were kept around the rewritten line, since it remains untestable with the current JWT encoding test libraries. - Behavior is unchanged. ### References Unblocks the Rector CI job on open PRs (#852, #853, #861). ### Testing - [ ] This change adds unit test coverage - [x] This change has been tested on the latest version of the platform/language ### Contributor Checklist - [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) - [x] I have read the [Auth0 code of conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
…id token getCredentials() gated enforcement on the id token, which is only rehydrated when persistIdToken is enabled, so a queued revocation was skipped when that option was off. Gate on the backchannel key instead, which is set only for a real session via exchange(). Add CookieStore and persistIdToken=false coverage.
kishore7snehil
force-pushed
the
fix/backchannel-logout-session-rehydration
branch
from
September 2, 2026 12:05
d9d925b to
80b57f4
Compare
rmad17
approved these changes
Sep 2, 2026
kishore7snehil
deleted the
fix/backchannel-logout-session-rehydration
branch
September 2, 2026 13:21
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Auth0::getState()rehydrated the user, id token, access token, scope, expiration, and refresh token from session storage, but not the backchannel key.setBackchannel()persists that key to session storage on login, yetgetState()never read it back, so on any subsequent requestgetBackchannel()returned null and the enforcement check ingetCredentials()short-circuited. A back-channel logout that had been queued was therefore not applied to later requests, and the session stayed authenticated.🐛 Bug Fix:
Auth0::getState()now rehydrates thebackchannelkey from session storage alongside the other persisted session values, so a queued back-channel logout is enforced on subsequent requestsSdkStateregistersbackchannelin its property defaults and validators, so the rehydrated value is accepted when the state is reconstructedgetCredentials()now gates the enforcement block on thebackchannelkey instead of the id token. The id token is only rehydrated whenpersistIdTokenis enabled, so with that option off the queued logout was skipped. The backchannel key is set only for a real session viaexchange(), so it separates a session from a bearer token just as well without depending on that settingReferences
N/A
Testing
getCredentials() enforces a queued backchannel logout on a subsequent requestlogs in, asserts a fresh instance sees the live session, queues a back-channel logout, then asserts a fresh instance reports no credentialsAdded a
CookieStorevariant covering the default storage backendAdded a
persistIdToken => falsevariant, the case where the id token is not rehydrated, which fails against the old id-token gateThis change adds unit test coverage
This change has been tested on the latest version of the platform/language
Contributor Checklist